OpenAIRE Graph API V3 — Follow-up Report
Date: 2026-07-15
Reporter: S. Mok, s.mok@utwente.nl
APIs tested: OpenAIRE Graph API V3 (/graph/v3/*), Scholexplorer V3 (/v3/Links)
Method: All issues from the previous report (2026-06-04) were re-verified against the live V3 endpoints using OAuth2 client credentials authentication, cross-referenced against the published OpenAPI specifications and the updated documentation at graph.openaire.eu/docs.

Thank you for releasing V3! This is a follow-up to the bug report we sent previously. We have re-tested every issue against the new V3 endpoints to see what has been resolved and what remains. We also list a few new issues we discovered while testing V3. As before, we report each issue separately without making assumptions about shared root causes.

Result: of the 21 issues in the previous report, 9 are resolved and 12 are still present in V3. We also found 4 new issues.

Summary Table

ID Severity Category Endpoint Issue V3 Status
BUG-S1 Critical Server Error /v3/persons givenName filter → 500 Fixed
BUG-S2 Critical Server Error /v3/persons lastName filter → 500 Fixed
BUG-D1 High Wrong Docs All entities debugQuery documented but doesn’t exist Resolved (removed)
BUG-D2 Medium Missing Docs Research products rorId works but not documented Fixed
BUG-D3 Medium Missing Docs All entities logicalOperator works but not documented Fixed
BUG-D4 High Missing Docs Persons No filtering docs (404) Fixed
BUG-D5 High Missing Docs Links Entire endpoint undocumented ❌ Still present
BUG-D6 Low Wrong Docs Data sources legalShortName description says “organization” ❌ Still present
BUG-D7 Low Wrong Docs Scholix spec Title typo “ScholeExplorer” ❌ Still present
BUG-D8 Low Wrong Docs Scholix spec page marked required but optional ❌ Still present
BUG-D9 Low Wrong Docs Data sources spec sortBy description says “organizations” ❌ Still present
BUG-D10 High Wrong Docs Persons spec sortBy includes non-functional startDate/endDate Fixed
BUG-D11 Medium Missing Docs V1/V2 V2 not documented; no deprecation notice Fixed
BUG-O1 Critical Behavior /v3/research-products/links pageSize=100 silently returns 10 ❌ Still present
BUG-O2 Critical Behavior Scholix size=100 silently returns 10 ❌ Still present
BUG-O3 Medium Behavior Research products Error message omits popularity sort field ❌ Still present
BUG-O4 Low Behavior Data sources Error message says “organizations” ❌ Still present
BUG-O5 Medium Data Quality Scholix Publisher IDURL always null Fixed
BUG-O6 Medium Consistency Links Different response header format ❌ Still present
BUG-O7 High Consistency Graph API Inconsistent page indexing (0 vs 1) ❌ Still present
BUG-O8 High Behavior Links Default pageSize=10, spec says 100 ❌ Still present

Issues Resolved in V3

The following issues from the previous report are now resolved. Thank you!

We also noticed and appreciate several general improvements in V3: the kebab-case URLs, many new and useful filter parameters across all entities, full cursor-based pagination on the regular endpoints, and proper pageSize validation (the regular endpoints now correctly accept up to 100 and reject larger values with a clean 400 instead of silently capping).

Issues Still Present in V3

The following 12 issues from the previous report are still present in V3. All reproductions below use the new V3 endpoints and were verified on 2026-07-15.

Documentation Issues

Endpoint: GET /v3/research-products/links and GET /v3/research-products/links/relations-info

Both endpoints exist in the V3 OpenAPI spec and work on the live API, but are still not documented anywhere on graph.openaire.eu/docs. The page /docs/apis/graph-api/research-products/links returns HTTP 404. There is no mention of the links endpoint or the relations-info endpoint in the navigation, searching, or filtering documentation.

BUG-D6: Data sources legalShortName description is wrong

Location: Documentation website (data sources filtering table) and V3 OpenAPI spec, /v3/datasources

The description for legalShortName still reads: “The legal name of the organization in short form.” This is a data source parameter — it should say “The legal name of the data source in short form.”

This is a copy-paste error from the organizations section, and it now appears in both the documentation website and the OpenAPI spec.

BUG-D7: Scholix OpenAPI spec title typo

Location: Scholexplorer OpenAPI spec (/api-docs/Scholexplorer%20API%20V3.0)

The spec title is still "ScholeExplorer APIs" — should be "Scholexplorer APIs" (the correct spelling used elsewhere). The extra e in “Scholeexplorer” is still present.

BUG-D8: Scholix page parameter still marked as required

Location: Scholexplorer OpenAPI spec, /v3/Links endpoint

The page parameter still has "required": true in the spec, but the API works fine without it (returns page 0 by default).

GET https://api.scholexplorer.openaire.eu/v3/Links?sourcePid=10.1016/j.respol.2021.104226&size=2
→ 200 {"currentPage": 0, "totalLinks": 121, ...}

Reproduction: curl "https://api.scholexplorer.openaire.eu/v3/Links?sourcePid=10.1016/j.respol.2021.104226&size=2"

BUG-D9: Data sources sortBy OpenAPI spec description says “organizations”

Location: V3 OpenAPI spec, /v3/datasources sortBy parameter

The sortBy parameter description still reads: “The field should be in the format ‘fieldname ASC|DESC’, organizations can be only sorted by the ‘relevance’.” This is a copy-paste error from the organizations endpoint — it should say “data sources” instead of “organizations”.

Behavioral Issues

Endpoint: GET /v3/research-products/links
Affected parameter: pageSize

Still present in V3. Requesting pageSize=100 silently falls back to 10 results with no error. The totalPages value confirms the server is using pageSize=10 internally.

pageSize Results returned totalPages Expected
10 10 13 13
50 50 3 3
99 99 2 2
100 10 13 2

Note: the regular V3 endpoints (e.g. /v3/research-products) now handle this correctly — pageSize=100 returns 100 and larger values return a proper 400. The defect is isolated to the links endpoint.

GET https://api.openaire.eu/graph/v3/research-products/links?sourcePid=10.1016/j.respol.2021.104226&pageSize=100&page=0
→ 200 {"header":{"page":0,"totalPages":13,"totalLinks":121},"results":[...10 items...]}

Reproduction: curl "https://api.openaire.eu/graph/v3/research-products/links?sourcePid=10.1016/j.respol.2021.104226&pageSize=100&page=0"
Effective maximum: 99

BUG-O2: size=100 silently returns 10 results on Scholix

Endpoint: GET /v3/Links (Scholexplorer)
Affected parameter: size

Still present. Identical behavior to BUG-O1. Requesting size=100 (the documented maximum: “max is 100”) silently returns 10 results.

size Results returned totalPages Expected
50 50 3 3
99 99 2 2
100 10 13 2
200 10 13 2
GET https://api.scholexplorer.openaire.eu/v3/Links?sourcePid=10.1016/j.respol.2021.104226&size=100
→ 200 {"currentPage":0,"totalLinks":121,"totalPages":13,"result":[...10 items...]}

Reproduction: curl "https://api.scholexplorer.openaire.eu/v3/Links?sourcePid=10.1016/j.respol.2021.104226&size=100"
Effective maximum: 99

BUG-O3: Research products sortBy error message omits popularity

Endpoint: GET /v3/research-products

Still present. When providing an invalid sortBy value, the error message lists valid fields as:

‘relevance’, ‘publicationDate’, ‘dateOfCollection’, ‘influence’, ‘citationCount’, ‘impulse’

But popularity is also a valid sort field (confirmed working with sortBy=popularity DESC, which returns 200). The error message is missing popularity, which makes it appear invalid when users encounter it via the error message.

GET https://api.openaire.eu/graph/v3/research-products?sortBy=invalid+DESC&pageSize=1
→ 400 {"message":"...research products can be only sorted by the 'relevance', 'publicationDate', 'dateOfCollection', 'influence', 'citationCount', 'impulse'."}

Note: The OpenAPI spec correctly includes popularity in the regex pattern. Only the error message is wrong.

Reproduction: curl "https://api.openaire.eu/graph/v3/research-products?sortBy=invalid+DESC&pageSize=1"

BUG-O4: Data sources sortBy error message says “organizations”

Endpoint: GET /v3/datasources

Still present. When providing an invalid sortBy value, the error message reads:

“organizations can be only sorted by the ‘relevance’”

This is the data sources endpoint, not organizations. Copy-paste error in the error message (same root cause as BUG-D9).

GET https://api.openaire.eu/graph/v3/datasources?sortBy=invalid+DESC&pageSize=1
→ 400 {"message":"...organizations can be only sorted by the 'relevance'."}

Reproduction: curl "https://api.openaire.eu/graph/v3/datasources?sortBy=invalid+DESC&pageSize=1"

Endpoints: GET /v3/research-products/links vs all other V3 Graph API endpoints

Still present. The links endpoint returns a completely different header structure from the other V3 Graph API endpoints:

Field Regular endpoints Links endpoint Scholix
numFound
maxScore
page ✅ (1-indexed) ✅ (0-indexed) ✅ (as currentPage, 0-indexed)
pageSize
totalPages
totalLinks
nextCursor ✅ (with cursor param)

The links endpoint also still lacks cursor-based pagination support, despite being a V3 Graph API endpoint.

BUG-O7: Page indexing is inconsistent between endpoints

Affected endpoints: All V3 Graph API endpoints

This is particularly confusing because the links endpoint is a V3 Graph API endpoint but uses different page indexing than the other V3 endpoints.

GET https://api.openaire.eu/graph/v3/research-products?search=covid&page=0&pageSize=1
→ 400 {"message":"page must be greater than 0"}

GET https://api.openaire.eu/graph/v3/research-products/links?sourcePid=10.1016/j.respol.2021.104226&page=0
→ 200 (first page of results)

Endpoint: GET /v3/research-products/links
Spec says: "default": 100
Actual: Default is 10

GET https://api.openaire.eu/graph/v3/research-products/links?sourcePid=10.1016/j.respol.2021.104226&page=0
→ 200 {"header":{"page":0,"totalPages":13,"totalLinks":121},"results":[...10 items...]}

With 121 total links and totalPages=13, the effective page size is 10. The spec claims the default is 100, which would produce totalPages=2.

New Issues Found in V3

The following issues were discovered while testing V3. They were not in the previous report.

NEW-1: info.version field still missing from all OpenAPI specifications

Location: All OpenAPI specifications (V3, V4-BETA, Scholexplorer)

None of the OpenAPI specifications include an info.version field. This was noted in the previous report’s general remarks and remains unresolved. Including info.version in each spec would let consumers programmatically detect which API version they are interacting with.

NEW-2: Scholexplorer /v3/api-docs endpoint returns HTTP 500

Location: https://api.scholexplorer.openaire.eu/v3/api-docs

The standard OpenAPI root path returns HTTP 500. The specification is only reachable via the group-specific path /api-docs/Scholexplorer%20API%20V3.0. Most OpenAPI/Swagger tooling expects the root api-docs path to work, so this causes integration failures.

GET https://api.scholexplorer.openaire.eu/v3/api-docs
→ 500

NEW-3: Filter values containing spaces require double-quoting (undocumented)

Affected endpoints: All V3 Graph API filter parameters that support logical operators

Filter values containing spaces, parentheses, or logical operators must be wrapped in double quotes. This is a powerful feature (it enables inline expressions like countryCode=("US" OR "GB") AND NOT "DE"), but the quoting requirement itself is not documented, and it is easy to hit by accident:

GET /v3/research-products?accessRightLabel=Open Access&pageSize=1
→ 400 {"message":"Invalid value for 'accessRightLabel'. Values containing spaces, parentheses or logical operators must be wrapped in double quotes, e.g. accessRightLabel=(\"value\")."}

GET /v3/research-products?accessRightLabel="Open Access"&pageSize=1
→ 200 (returns results)

Recommendation: Document the quoting and logical-operator syntax for filter values prominently in the filtering guide, including the list of operators (AND, OR, NOT) and examples.

NEW-4: Several filter parameters have undocumented allowed values

Affected parameters: accessRightLabel, sdgLabel, openAccessColor, influenceClass, popularityClass, impulseClass, citationCountClass

These parameters accept only a specific set of string values, but the OpenAPI spec declares them as plain type: string without an enum. The only way to discover the valid values is to submit an invalid one and read the 400 error message. For example:

GET /v3/research-products?accessRightLabel=OPEN
→ 400 {"message":"Invalid value: 'OPEN' in 'accessRightLabel'. Allowed values are: ['Open Access', 'Closed Access', 'Restricted', 'Open Source', 'Embargo', 'Unknown']"}

Known allowed values discovered this way:

Recommendation: Declare these as enum constraints in the OpenAPI spec so that clients and code generators can discover the valid values without trial and error.

Version Numbering

As a final general remark (carried over from the previous report): the version numbering remains somewhat confusing. The OpenAPI spec URLs live under /graph/v3/api-docs/, where v3 is the Springdoc group name rather than a clear API version marker; the actual V3 API paths use /v3/; and none of the specs include an info.version field. We understand V3 is now the single recommended version (V1/V2 deprecated), which already simplifies things considerably. Adding info.version to each spec would make the remaining ambiguity easy to resolve programmatically.